﻿using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using CommandLine;
using MyOS.Models;
using MyOS.Utils;
using MyOS.ViewModel;

namespace MyOS
{
    internal static class Program
    {
        private static FileStream readFileStream;
        private static FileViewModel viewModel;

        /// <summary>
        ///     应用程序的主入口点。
        /// </summary>
        [STAThread]
        private static int Main(string[] args)
        {
            if (args.Length == 0)
            {
                var app = new App();
                app.InitializeComponent();
                var windows = new MainWindow();
                app.MainWindow = windows;
                app.Run();
                return 0;
            }

            try
            {
                IFormatter formatter = new BinaryFormatter();
                readFileStream = new FileStream("objMenuItem", FileMode.Open);
                viewModel = (FileViewModel) formatter.Deserialize(readFileStream);
                readFileStream.Close();
            }
            catch (Exception e)
            {
                DiskUtils.saveObjectToFile(new FileViewModel());
            }

            var exitCode = Parser.Default.ParseArguments<
                CommandUtils.CreateFileOptions, CommandUtils.CopyFileOptions, CommandUtils.RemoveFileOption,
                CommandUtils.MoveFileOption, CommandUtils.OpenFileOption, CommandUtils.EditFileOption,
                CommandUtils.ChangePermissionOption, CommandUtils.FormatDiskOption, CommandUtils.MakeDirOption,
                CommandUtils.ChangeDirOption>(args).MapResult(
                (CommandUtils.CreateFileOptions o) => CreateFile(o),
                (CommandUtils.CopyFileOptions o) => CopyFile(o),
                (CommandUtils.RemoveFileOption o) => RemoveFile(o),
                (CommandUtils.MoveFileOption o) => MoveFile(o),
                (CommandUtils.OpenFileOption o) => OpenFile(o),
                (CommandUtils.EditFileOption o) => EditFile(o),
                (CommandUtils.ChangePermissionOption o) => ChangePermission(o),
                (CommandUtils.FormatDiskOption o) => FormatDisk(o),
                (CommandUtils.MakeDirOption o) => MakeDir(o),
                (CommandUtils.ChangeDirOption o) => ChangeDir(o),
                error => 1);

            return exitCode;
        }

        #region 创建文件，细节待修改

        private static int CreateFile(CommandUtils.CreateFileOptions options)

        {
            var fileName = options.NewFile;
            var fileSize = options.FileSize;
            //bool isOverwrite = options.Overwrite;
            var targetDir = options.TargetDir;
            if (fileSize < 1)
            {
                Console.WriteLine("文件未创建。文件大小必须大于0 Byte。");
                return -1;
            }

            var path = targetDir.Split("/");

            try
            {
                var diskName = char.ToUpper(Convert.ToChar(path[2]));
                var start = DiskUtils.findEmptyBlock(diskName, fileSize);
                if (start == -1)
                {
                    Console.WriteLine("文件未创建。磁盘空间不足。");
                    return -2;
                }

                if (fileName.Length > 3)
                {
                    Console.WriteLine("文件名过长。(MaxLength=3)");
                    return -3;
                }

                var attrBytes = new byte[20];
                var folderNameBytes = Encoding.Default.GetBytes(fileName);
                for (var i = 0; i < folderNameBytes.Length; i++) attrBytes[i] = folderNameBytes[i];

                attrBytes[3] = Convert.ToByte('e');
                attrBytes[4] = 3;
                attrBytes[5] = Convert.ToByte(start); //起始盘块号
                attrBytes[6] = BitConverter.GetBytes(fileSize)[0]; //文件长度
                attrBytes[7] = BitConverter.GetBytes(fileSize)[1]; //文件长度
                attrBytes[8] = Convert.ToByte(DateTime.Now.ToString("yy")); //创建时间
                attrBytes[9] = Convert.ToByte(DateTime.Now.Month);
                attrBytes[10] = Convert.ToByte(DateTime.Now.Day);
                attrBytes[11] = Convert.ToByte(DateTime.Now.Hour);
                attrBytes[12] = Convert.ToByte(DateTime.Now.Minute);
                attrBytes[13] = Convert.ToByte(DateTime.Now.Second);
                DiskUtils.writeToRoot(diskName, attrBytes);
                DiskUtils.writeToFatAndDisk(diskName, new byte[fileSize], start); //创建一个指定大小的空文件
                Console.WriteLine(fileName + " 写入完成。目标磁盘:" + diskName + ",文件大小:" + fileSize + "Byte");
                if (diskName == 'C')
                    viewModel.DiskCModel.MenuItems.Add(new FileTreeViewItemModel(fileName, 'e', "\uf0f6"));
                else
                    viewModel.DiskDModel.MenuItems.Add(new FileTreeViewItemModel(fileName, 'e', "\uf0f6"));
                DiskUtils.saveObjectToFile(viewModel);
            }
            catch (Exception e)
            {
                Console.WriteLine("'" + path[2] + "'" + "不是一个正确的磁盘。(C,D)");
            }

            return 0;
        }

        #endregion

        #region 复制文件

        private static int CopyFile(CommandUtils.CopyFileOptions options)
        {
            var isOverwrite = options.Overwrite;
            var sourceFile = options.SourceFile;
            var targetDir = options.TargetDir;
            return 0;
        }

        #endregion


        #region 移动文件

        private static int RemoveFile(CommandUtils.RemoveFileOption option)
        {
            var originFilePath = option.TargetFile.Split("/");
            var targetFilePath = option.TargetDir.Split("/");
            var fileType = option.TargetType;
            if (originFilePath[2] == null || targetFilePath[2] == null)
            {
                Console.WriteLine("目标文件或源文件不能是根目录！");
                return -1;
            }

            if (char.ToUpper(Convert.ToChar(originFilePath[2])) != 'C' ||
                char.ToUpper(Convert.ToChar(originFilePath[2])) != 'D')
            {
                Console.WriteLine("源文件磁盘错误。磁盘必须是'C'/'D'");
                return -2;
            }

            if (char.ToUpper(Convert.ToChar(targetFilePath[2])) != 'C' ||
                char.ToUpper(Convert.ToChar(targetFilePath[2])) != 'D')
            {
                Console.WriteLine("目标文件磁盘错误。磁盘必须是'C'/'D'");
                return -2;
            }

            var originDisk = Convert.ToChar(originFilePath[2]);
            var targetDisk = Convert.ToChar(targetFilePath[2]);

            //DiskUtils.readFile(originDisk, originFile.FileName); //从原磁盘读文件
            var fileBytes = DiskUtils.FileBytes;
            return 0;
        }

        #endregion


        private static int MoveFile(CommandUtils.MoveFileOption option)
        {
            return 0;
        }

        private static int OpenFile(CommandUtils.OpenFileOption option)
        {
            return 0;
        }

        public static int EditFile(CommandUtils.EditFileOption option)
        {
            return 0;
        }

        public static int ChangePermission(CommandUtils.ChangePermissionOption option)
        {
            return 0;
        }

        public static int FormatDisk(CommandUtils.FormatDiskOption option)
        {
            return 0;
        }

        public static int MakeDir(CommandUtils.MakeDirOption option)
        {
            return 0;
        }

        private static int ChangeDir(CommandUtils.ChangeDirOption option)
        {
            return 0;
        }
    }
}